package com.arquitectonic.client.datosYlogica;

import java.util.Collection;

import com.arquitectonic.client.datosYlogica.GestorLogin.ProgressData;
import com.arquitectonic.client.datosYlogica.vistas.Vista;
import com.arquitectonic.client.extensiones.Gestor;
import com.arquitectonic.client.extensiones.Par;
import com.arquitectonic.client.servicios.Proxy;
import com.arquitectonic.compartido.Preferencia;
import com.arquitectonic.compartido.ServerException;
import com.arquitectonic.compartido.Stakeholder;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.DataSourceField;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.form.validator.FloatRangeValidator;
import com.smartgwt.client.widgets.form.validator.IntegerRangeValidator;
import com.smartgwt.client.widgets.grid.ListGridRecord;

public class GestorStakeholders extends Gestor<Stakeholder> {

	private static GestorStakeholders instance = null;

	public static GestorStakeholders getInstance() {
		if (instance == null) {
			instance = new GestorStakeholders();
		}
		return instance;
	}

	public GestorStakeholders() {
		super("Stakeholders");
	}

	// DONE
	static AsyncCallback<Collection<Stakeholder>> callbackGetStakeholders = new AsyncCallback<Collection<Stakeholder>>() {
		@Override
		public void onSuccess(Collection<Stakeholder> result) {

			getInstance().cargarDatos(result);

			for (Stakeholder s : result) {
				GestorPreferencias.agregarStakeholder(s);
			}
			ProgressData.getInstance().dataSourceFinalizado();
		}

		@Override
		public void onFailure(Throwable caught) {
			SC.warn(caught.getMessage());
		}
	};

	public static void cargarStakeholders() throws ServerException {
		Proxy.getServicios().getStakeholders(callbackGetStakeholders);
	}

	// DONE
	static AsyncCallback<Boolean> callbackAddStakeholder = new AsyncCallback<Boolean>() {
		@Override
		public void onSuccess(Boolean result) {
			getInstance().agregarElemento(saux);
			GestorPreferencias.agregarStakeholder(saux);
		}

		@Override
		public void onFailure(Throwable caught) {
			SC.warn(caught.getMessage());
		}
	};

	static AsyncCallback<String[]> callbackGetRoles = new AsyncCallback<String[]>() {
		@Override
		public void onSuccess(String[] result) {

			rolesPosibles = result;
		}

		@Override
		public void onFailure(Throwable caught) {
			SC.warn(caught.getMessage());
		}
	};

	public static String[] tiposDeVistasPosibles;

	static AsyncCallback<String[]> callBackGetTiposVistasPosibles = new AsyncCallback<String[]>() {

		@Override
		public void onSuccess(String[] result) {
			tiposDeVistasPosibles = result;
		}

		@Override
		public void onFailure(Throwable caught) {
			SC.warn(caught.getMessage());
		}
	};

	static {
		Proxy.getServicios().getTiposVistasPosibles(
				callBackGetTiposVistasPosibles);
	}

	static public String[] rolesPosibles;

	static {
		Proxy.getServicios().getRoles(callbackGetRoles);
	}

	// private static Record raux;
	private static Stakeholder saux;

	public static void agregarStakeholder(Record r) {
		try {
			r.setAttribute("satisfaccion", "SATISFECHO");
			saux = getInstance().toDato(r);
			if (getInstance().getElemento(saux.getNombreStakeholder()) != null)
				throw new Exception("el stakeholder ya existe");
			// llamo al servicio asincronico
			Proxy.getServicios().addStakeholder(saux, callbackAddStakeholder);
		} catch (Exception e) {
			SC.warn(e.getMessage());
		}
	}

	// DONE
	static AsyncCallback<Boolean> callbackDelStakeholder = new AsyncCallback<Boolean>() {
		@Override
		public void onSuccess(Boolean result) {
			if (result.booleanValue()) {
				getInstance().removerElemento(saux.getNombreStakeholder());
				GestorPreferencias.borrarStakeholder(saux);
			}
		}

		@Override
		public void onFailure(Throwable caught) {
			SC.warn(caught.getMessage());
		}
	};

	public static void borrarStakeholder(Record r) {
		try {
			if (r == null)
				throw new Exception(
						"Seleccione un stakeholder de la lista para eliminarlo");
			else {
				saux = getInstance().getElemento(
						r.getAttribute("nombreStakeholder"));
				if (saux != null) {
					Proxy.getServicios()
							.delStakeholder(saux.getNombreStakeholder(),
									callbackDelStakeholder);
				}
			}
		} catch (Exception e) {
			SC.warn(e.getMessage());
		}
	}

	public static void actualizarStakeholder(String nombreStakeholder,
			String satisfaccion) {
		getInstance().actualizarElemento(nombreStakeholder, "satisfaccion",
				satisfaccion);

	
	}

	public static void actualizarSatisfaccionStakeholders() {
		Collection<Stakeholder> stakeholders = getInstance().getElementos();
		for (Stakeholder s : stakeholders) {
			actualizarSatisfaccionStakeholder(s.getNombreStakeholder());
		}
	}

	public static void actualizarSatisfaccionStakeholder(
			String nombreStakeholder) {
		Collection<Preferencia> preferencias = GestorPreferencias
				.getPreferenciasStakeholder(nombreStakeholder);
		if (preferencias == null || preferencias.isEmpty()) {
			actualizarStakeholder(nombreStakeholder, Stakeholder.SATISFECHO);
		} else {
			boolean satisfecho = true;
			for (Preferencia p : preferencias) {
				Vista v = GestorVistas.getInstance().getElemento(
						p.getNombreVista());
				if (v.getNivelDeDetalle() < p.getNivelDeseado()) {
					satisfecho = false;
					break;
				}
			}
			if (satisfecho)
				actualizarStakeholder(nombreStakeholder, Stakeholder.SATISFECHO);
			else
				actualizarStakeholder(nombreStakeholder,
						Stakeholder.INSATISFECHO);
		}
	}

	@Override
	protected ListGridRecord toListGridRecord(Stakeholder d) {
		ListGridRecord r = new ListGridRecord();
		r.setAttribute("nombreStakeholder", d.getNombreStakeholder());
		r.setAttribute("prioridad", d.getPrioridad());
		r.setAttribute("cantidad", d.getCantidad());
		r.setAttribute("roles", d.getRoles());
		r.setAttribute("satisfaccion", d.getSatisfaccion());
		return r;
	}

	protected Stakeholder toDato(Record r) {
		return new Stakeholder(r.getAttribute("nombreStakeholder"),
				r.getAttribute("prioridad"), r.getAttribute("cantidad"),
				r.getAttribute("roles"), r.getAttribute("satisfaccion"));
	}

	@Override
	protected boolean actualizarCampo(Par<Stakeholder, ListGridRecord> dato,
			String campo, Object valor) {
		if (campo.equals("satisfaccion")) {
			dato.primero.setSatisfaccion((String) valor);
			dato.segundo.setAttribute("satisfaccion", (String) valor);
			return true;
		}
		return false;
	}

	@Override
	public String obtenerClave(Stakeholder dato) {
		return dato.getNombreStakeholder();
	}

	@Override
	protected DataSourceField[] getDataSourceFields() {

		// Campo Stakeholder:
		DataSourceTextField stakeholderNombre = new DataSourceTextField(
				"nombreStakeholder", "Nombre");
		stakeholderNombre.setPrimaryKey(true);
		stakeholderNombre.setRequired(true);

		// Campo prioridad:
		DataSourceTextField stakeholderPrioridad = new DataSourceTextField(
				"prioridad", "Prioridad");
		stakeholderPrioridad.setRequired(true);
		FloatRangeValidator restriccionPrioridad = new FloatRangeValidator();
		restriccionPrioridad.setMax(1.0f);
		restriccionPrioridad.setMin(0.0f);
		stakeholderPrioridad.setValidators(restriccionPrioridad);

		// Campo cantidad:
		DataSourceTextField stakeholderCantidad = new DataSourceTextField(
				"cantidad", "Cantidad");
		stakeholderCantidad.setRequired(true);
		IntegerRangeValidator restriccionCantidad = new IntegerRangeValidator();
		restriccionCantidad.setMax(Integer.MAX_VALUE);
		restriccionCantidad.setMin(1);
		stakeholderCantidad.setValidators(restriccionCantidad);

		// Campo roles:
		DataSourceTextField stakeholderRoles = new DataSourceTextField("roles",
				"Roles");
		stakeholderRoles.setRequired(true);

		// Campo satisfaccion:
		DataSourceTextField stakeholderSatisfaccion = new DataSourceTextField(
				"satisfaccion", "Satisfaccion");
		stakeholderSatisfaccion.setValueMap(Stakeholder.NIVEL_SATISFACCION);

		return new DataSourceField[] { stakeholderNombre, stakeholderPrioridad,
				stakeholderCantidad, stakeholderRoles, stakeholderSatisfaccion };
	}

}
